﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Reflection;
using EnvDTE;
using EnvDTE80;

namespace VSAddInFramework
{

    // Manage Addin commands
    public static class VSCommandMgr
    {
        static VSCommandMgr()
        {
            m_CmdTable = new Dictionary<string, VSCommand>();
            m_CmdGroupList = new List<VSCommandGroup>();
        }

        public static void AddCommand(VSCommand cmd)
        {
            m_CmdTable.Add(cmd.InternalName, cmd);

            Commands2 commands = VSAddInMgr.Instance.Application.Commands as Commands2;
            Debug.Assert(commands != null);

            if (commands != null)
            {
                // If the command already exists, just get it.
                try
                {
                    cmd.InternalCommand = commands.Item(cmd.InternalName, 0);
                }
                catch { }

                if (cmd.InternalCommand == null)
                {
                    cmd.InternalCommand = commands.AddNamedCommand2(VSAddInMgr.Instance.AddIn, cmd.Name, cmd.ButtonText, cmd.ToolTip,
                                     cmd.MSOButton, cmd.Bitmap, ref VSCommand.contextGUIDS, cmd.CommandStatsValue, cmd.CommandStyleFlags, cmd.ControlType);
                }

            }
        }

        public static void AddCommandGroup(VSCommandGroup cmdGroup)
        {
            Debug.Assert(cmdGroup != null);
            m_CmdGroupList.Add(cmdGroup);

            foreach (VSCommand cmd in cmdGroup.VSCommands)
            {
                AddCommand(cmd);
            }
        }

        public static VSCommand GetCommand(string cmdInternalName)
        {
            VSCommand cmd = m_CmdTable[cmdInternalName];
            Debug.Assert(cmd != null);
            return cmd;
        }


        public static void CreateCommandsUI()
        {
            // Add command to an organized toolbar according to command group
            foreach (VSCommandGroup cmdGroup in m_CmdGroupList)
            {
                try
                {
                    cmdGroup.CreateCommandsUI();
                }
                catch { }
            }

            // Add command to context menu that you think appropriate.
            Dictionary<string, VSCommand>.ValueCollection cmdColl = m_CmdTable.Values;
            foreach (VSCommand cmd in cmdColl)
            {
                try
                {
                    cmd.CreateCommandUI();
                }
                catch { }
            }
        }


        public static void DestroyCommandsUI()
        {
            // Delete commandbars
            foreach (VSCommandGroup cmdGroup in m_CmdGroupList)
            {
                cmdGroup.DestroyCommandsUI();
            }

            // Remove buttons from native toolbars, context menus...
            Dictionary<string, VSCommand>.ValueCollection cmdColl = m_CmdTable.Values;
            foreach (VSCommand cmd in cmdColl)
            {
                cmd.DestoryCommandUI();
            }
        }

        private static Dictionary<string, VSCommand> m_CmdTable; // = new Dictionary<string, VSCommand>();
        private static List<VSCommandGroup> m_CmdGroupList;

    }
}
